//
//  limb.cpp
//  template4
//
//  Created by Xiaochen Lian on 5/15/12.
//  Copyright (c) 2012 University of California, Los Angeles. All rights reserved.
//

#include "limb.h"

//----------------------------------------------------------------------------
// ILimb
ILimb::ILimb(const vec4 &pos, GLfloat length)
{
    m_length = length;
    set_pos(pos);
}

void ILimb::set_material(const lighting_struct &material)
{
    m_material = material;
}

void ILimb::draw(const mat4 &tfm_parent) 
{
    glUniform4fv(uAmbient, 1, g_env_lighting.ambient * m_material.ambient);
    glUniform4fv(uDiffuse, 1, g_env_lighting.diffuse.x * m_material.diffuse);
    glUniform4fv(uSpecular, 1, g_env_lighting.specular * m_material.specular);
    glUniform1f(uShininess, g_env_lighting.shininess * m_material.shininess);
    // draw objects
    //        glBindVertexArray( m_shape_data.vao );
    //        for (int i = 0; i < m_children.size(); ++i)
    //            m_children[i]->draw(light_pos, env_lighting, pMc, cMw, tfm_parent*m_tfm);
    drawCube(tfm_parent*m_tfm*m_scale_mat);
    
    for (int i = 0; i < m_children.size(); ++i)
        m_children[i]->draw(tfm_parent*m_tfm);
}

//----------------------------------------------------------------------------
// CShoulder
CShoulder::CShoulder(const vec4 &pos, GLfloat length)
:ILimb(pos, length)
{
    m_type = SHOULDER;
}

void CShoulder::build_model()
{
    const GLfloat forearm_length = m_length > 0 ? 5.0f : -5.0f;

    m_tfm = Translate(m_model_pos);
    m_scale_mat = Scale(abs(m_length), 1.0f, 1.0f);
    
    m_material.ambient = color4( 0.4f, 0.5f, 0.4f, 1.0f );
    m_material.diffuse = color4( 0.4f, 0.5f, 0.4f, 1.0f );
    m_material.specular = color4( 0.1f, 0.1f, 0.1f, 1.0f );
    m_material.shininess = 10.0f;
        
    CForearm *forearm = new CForearm(vec4((m_length+forearm_length)/2, 0.0f, 0.0f, 0.0f), forearm_length);
    m_children.push_back(forearm);
    
    // TO DO: feather
    
    for (int i = 0; i < m_children.size(); ++i)
        m_children[i]->build_model();
}

//----------------------------------------------------------------------------
// CForearm
CForearm::CForearm(const vec4 &pos, GLfloat length)
:ILimb(pos, length)
{
    m_type = FOREARM;
}

void CForearm::build_model()
{
    const GLfloat forearm_length = m_length > 0 ? 3.0f : -3.0f;
    m_tfm = Translate(m_model_pos);
    m_scale_mat = Scale(abs(m_length), 1.0f, 1.0f);
    
    m_material.ambient = color4( 0.5f, 0.4f, 0.4f, 1.0f );
    m_material.diffuse = color4( 0.5f, 0.4f, 0.4f, 1.0f );
    m_material.specular = color4( 0.1f, 0.1f, 0.1f, 1.0f );
    m_material.shininess = 10.0f;

    CWrist *wrist = new CWrist(vec4((m_length+forearm_length)/2, 0.0f, 0.0f, 0.0f), forearm_length);
    m_children.push_back(wrist);
    
    // TO DO: feather
    
    for (int i = 0; i < m_children.size(); ++i)
        m_children[i]->build_model();
}

//----------------------------------------------------------------------------
// CWrist
CWrist::CWrist(const vec4 &pos, GLfloat length)
:ILimb(pos, length)
{
    m_type = WRIST;
}

void CWrist::build_model()
{
    m_tfm = Translate(m_model_pos);
    m_scale_mat = Scale(abs(m_length), 1.0f, 1.0f);
    
    m_material.ambient = color4( 0.4f, 0.4f, 0.5f, 1.0f );
    m_material.diffuse = color4( 0.4f, 0.4f, 0.5f, 1.0f );
    m_material.specular = color4( 0.1f, 0.1f, 0.1f, 1.0f );
    m_material.shininess = 10.0f;
    // TO DO: feather
    
    for (int i = 0; i < m_children.size(); ++i)
        m_children[i]->build_model();
}